package evolution.algorithm;

import evolution.individual.Individual;
import evolution.operation.mutation.MutationStrategy;
import evolution.operation.reproduction.ReproductionStrategy;
import evolution.operation.selection.SelectionStrategy;
import evolution.operation.succession.SuccessionStrategy;
import evolution.problem.OptimizationProblem;

public class EvolutionaryAlgorithm implements Iterative {

	private MutationStrategy mutator;
	private ReproductionStrategy reproductor;
	private SelectionStrategy selector;
	private SuccessionStrategy successor;
	private int currentIteration = 0;
	private Individual[] population;
	private OptimizationProblem optimizationProblem;

	@Override
	public void runIteration() {
		currentIteration++;

		Individual[] selected = selector.select(population);
		Individual[] offspring = reproductor.breed(selected);

		mutator.mutate(offspring);

		Individual[] nextGeneration = successor.success(population, offspring);
		population = nextGeneration;
	}

	public MutationStrategy getMutator() {
		return mutator;
	}

	public void setMutator(MutationStrategy mutator) {
		this.mutator = mutator;
	}

	public ReproductionStrategy getReproductor() {
		return reproductor;
	}

	public void setReproductor(ReproductionStrategy reproductor) {
		this.reproductor = reproductor;
	}

	public SelectionStrategy getSelector() {
		return selector;
	}

	public void setSelector(SelectionStrategy selector) {
		this.selector = selector;
	}

	@Override
	public int getCurrentIteration() {
		return currentIteration;
	}

	public SuccessionStrategy getSuccessor() {
		return successor;
	}

	public void setSuccessor(SuccessionStrategy successor) {
		this.successor = successor;
	}

	public Individual[] getPopulation() {
		return population;
	}

	public void setPopulation(Individual[] population) {
		this.population = population;
	}

	public OptimizationProblem getOptimizationProblem() {
		return optimizationProblem;
	}

	public void setOptimizationProblem(OptimizationProblem optimizationProblem) {
		this.optimizationProblem = optimizationProblem;
	}

}